package com.jack.thinking.java._22.swing.concurrent;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.swing.*;

import com.utils.SwingConsole;

/**
 * 这里涉及到了 多线程中修改组件的问题：
 * 看上去违反了只向事件队列中提交任务的原则， 但是，这些线程并未实际修改共享资源。当它们调用repaint(), 并未强制在这一时刻立即进行绘制，
 * 而只是设置了一个脏标志， 表示当下一个事件分发线程准备好重绘时， 这个区域是是重绘的备选元素之一，因此不会引起Swing的多线程问题。
 * @author wangbingwu
 *
 */
public class ColorBoxes extends JFrame{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int grid = 12;
	private int pause = 50;
	private static ExecutorService exec = Executors.newCachedThreadPool();
	
	public void setUp() {
		setLayout(new GridLayout(grid, grid));
		for(int i = 0; i < grid * grid; i++) {
			CBox cb = new CBox(pause);
			add(cb);
			exec.execute(cb);
		}
	}
	
	public static void main(String[] args) {
		ColorBoxes boxes = new ColorBoxes();
		if(args.length > 0) {
			boxes.grid = new Integer(args[0]);
		}
		if(args.length > 1) {
			boxes.pause = new Integer(args[1]);
		}
		
		boxes.setUp();
		
		SwingConsole.run(boxes, 500, 400);
	}
}


class CBox extends JPanel implements Runnable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private int pause;
	private static Random rand = new Random();
	private Color color  = new Color(0);
	
	@Override
	protected void paintComponent(Graphics g) {
		g.setColor(color);
		Dimension s = getSize();
		g.fillRect(0, 0, s.width, s.height);
	}
	
	public CBox(int pause) {
		this.pause = pause;
	}

	@Override
	public void run() {
		try {
			while(!Thread.interrupted()) {
				color = new Color(rand.nextInt(0xFFFFFF));
				repaint();
				TimeUnit.MILLISECONDS.sleep(pause);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}